プラットフォーム ビューを使用して Flutter アプリでネイティブ iOS ビューをホストする
プラットフォーム ビューを使用すると、Flutter アプリにネイティブ ビューを埋め込むことができます。 ネイティブ ビューに変換、クリップ、不透明度を適用できるようになります。 ダーツから。
これにより、たとえばネイティブの Android および iOS SDK からの Google マップ Flutter アプリ内で直接。
iOSはハイブリッド合成のみを使用しますが、
つまりネイティブはUIView
ビュー階層に追加されます。
iOS でプラットフォーム ビューを作成するには、 次の手順を使用してください。
ダーツ側では
Dart 側で、Widget
そしてビルド実装を追加します。
次の手順に示すように。
Dart ウィジェット ファイルで、次のような変更を加えます。
に示されているnative_view_example.dart
:
-
次のインポートを追加します。
import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart';
-
を実装します。
build()
方法:Widget build(BuildContext context) { // This is used in the platform side to register the view. const String viewType = '<platform-view-type>'; // Pass parameters to the platform side. final Map<String, dynamic> creationParams = <String, dynamic>{}; return UiKitView( viewType: viewType, layoutDirection: TextDirection.ltr, creationParams: creationParams, creationParamsCodec: const StandardMessageCodec(), ); }
詳細については、次の API ドキュメントを参照してください。UIKitView
。
ホーム側
プラットフォーム側では、Swift または Objective-C のいずれかを使用します。
ファクトリ ビューとプラットフォーム ビューを実装します。
のFLNativeViewFactory
プラットフォームビューを作成し、
プラットフォーム ビューは、UIView
。
例えば、FLNativeView.swift
:
import Flutter
import UIKit
class FLNativeViewFactory: NSObject, FlutterPlatformViewFactory {
private var messenger: FlutterBinaryMessenger
init(messenger: FlutterBinaryMessenger) {
self.messenger = messenger
super.init()
}
func create(
withFrame frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?
) -> FlutterPlatformView {
return FLNativeView(
frame: frame,
viewIdentifier: viewId,
arguments: args,
binaryMessenger: messenger)
}
/// Implementing this method is only necessary when the `arguments` in `createWithFrame` is not `nil`.
public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
return FlutterStandardMessageCodec.sharedInstance()
}
}
class FLNativeView: NSObject, FlutterPlatformView {
private var _view: UIView
init(
frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?,
binaryMessenger messenger: FlutterBinaryMessenger?
) {
_view = UIView()
super.init()
// iOS views can be created here
createNativeView(view: _view)
}
func view() -> UIView {
return _view
}
func createNativeView(view _view: UIView){
_view.backgroundColor = UIColor.blue
let nativeLabel = UILabel()
nativeLabel.text = "Native text from iOS"
nativeLabel.textColor = UIColor.white
nativeLabel.textAlignment = .center
nativeLabel.frame = CGRect(x: 0, y: 0, width: 180, height: 48.0)
_view.addSubview(nativeLabel)
}
}
最後にプラットフォームビューを登録します。 これはアプリまたはプラグインで実行できます。
アプリの登録については、
アプリを変更するAppDelegate.swift
:
import Flutter
import UIKit
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
weak var registrar = self.registrar(forPlugin: "plugin-name")
let factory = FLNativeViewFactory(messenger: registrar!.messenger())
self.registrar(forPlugin: "<plugin-name>")!.register(
factory,
withId: "<platform-view-type>")
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
プラグインの登録については、
プラグインのメインファイルを変更する
(例えば、FLPlugin.swift
):
import Flutter
import UIKit
class FLPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let factory = FLNativeViewFactory(messenger: registrar.messenger())
registrar.register(factory, withId: "<platform-view-type>")
}
}
Objective-C で、ファクトリとプラットフォーム ビューのヘッダーを追加します。
たとえば、次のようにFLNativeView.h
:
#import <Flutter/Flutter.h>
@interface FLNativeViewFactory : NSObject <FlutterPlatformViewFactory>
- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
@end
@interface FLNativeView : NSObject <FlutterPlatformView>
- (instancetype)initWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
- (UIView*)view;
@end
ファクトリ ビューとプラットフォーム ビューを実装します。
のFLNativeViewFactory
プラットフォームビューを作成し、
プラットフォーム ビューは、UIView
。例えば、FLNativeView.m
:
#import "FLNativeView.h"
@implementation FLNativeViewFactory {
NSObject<FlutterBinaryMessenger>* _messenger;
}
- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
self = [super init];
if (self) {
_messenger = messenger;
}
return self;
}
- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args {
return [[FLNativeView alloc] initWithFrame:frame
viewIdentifier:viewId
arguments:args
binaryMessenger:_messenger];
}
/// Implementing this method is only necessary when the `arguments` in `createWithFrame` is not `nil`.
- (NSObject<FlutterMessageCodec>*)createArgsCodec {
return [FlutterStandardMessageCodec sharedInstance];
}
@end
@implementation FLNativeView {
UIView *_view;
}
- (instancetype)initWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
if (self = [super init]) {
_view = [[UIView alloc] init];
}
return self;
}
- (UIView*)view {
return _view;
}
@end
最後にプラットフォームビューを登録します。 これはアプリまたはプラグインで実行できます。
アプリの登録については、
アプリを変更するAppDelegate.m
:
#import "AppDelegate.h"
#import "FLNativeView.h"
#import "GeneratedPluginRegistrant.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
NSObject<FlutterPluginRegistrar>* registrar =
[self registrarForPlugin:@"plugin-name"];
FLNativeViewFactory* factory =
[[FLNativeViewFactory alloc] initWithMessenger:registrar.messenger];
[[self registrarForPlugin:@"<plugin-name>"] registerViewFactory:factory
withId:@"<platform-view-type>"];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
プラグインの登録については、
メインのプラグインファイルを変更する
(例えば、FLPlugin.m
):
#import <Flutter/Flutter.h>
#import "FLNativeView.h"
@interface FLPlugin : NSObject<FlutterPlugin>
@end
@implementation FLPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FLNativeViewFactory* factory =
[[FLNativeViewFactory alloc] initWithMessenger:registrar.messenger];
[registrar registerViewFactory:factory withId:@"<platform-view-type>"];
}
@end
詳細については、次の API ドキュメントを参照してください。
FlutterPlatformViewFactory
FlutterPlatformView
PlatformView
それを一緒に入れて
実装する際には、build()
Dartのメソッド、
使用できます9a7736c7-83e4-4dd0-b787-0dbfaf43207bプラットフォームを検出し、どのウィジェットを使用するかを決定します。
Widget build(BuildContext context) {
// This is used in the platform side to register the view.
const String viewType = '<platform-view-type>';
// Pass parameters to the platform side.
final Map<String, dynamic> creationParams = <String, dynamic>{};
switch (defaultTargetPlatform) {
case TargetPlatform.android:
// return widget on Android.
case TargetPlatform.iOS:
// return widget on iOS.
default:
throw UnsupportedError('Unsupported platform view');
}
}
パフォーマンス
Flutter のプラットフォーム ビューにはパフォーマンスのトレードオフが伴います。
たとえば、典型的な Flutter アプリでは、Flutter UI は次のようになります。 専用のラスター スレッドで構成されます。 これにより、Flutter アプリが高速になります。 メインプラットフォームのスレッドがブロックされることはほとんどないためです。
プラットフォーム ビューがハイブリッド構成でレンダリングされる場合、 Flutter UI はプラットフォーム スレッドから構成されます。 プラットフォームのスレッドが他のタスクと競合する OS やプラグインのメッセージの処理など。
iOS PlatformView が画面上にある場合、画面のリフレッシュ レートは次のようになります。 レンダリングのジャンクを避けるために 80fps に制限されています。
複雑なケースの場合、使用できるテクニックがいくつかあります パフォーマンスの問題を軽減します。
たとえば、プレースホルダー テクスチャを使用しながら、 Dartでアニメーションが起こっています。 言い換えれば、プラットフォーム ビューのレンダリング中にアニメーションが遅い場合、 次に、ネイティブ ビューのスクリーンショットを取得し、それをテクスチャとしてレンダリングすることを検討してください。
構成の制限
iOS プラットフォーム ビューを作成する場合には、いくつかの制限があります。
- の
ShaderMask
とColorFiltered
ウィジェットはサポートされていません。 - の
BackdropFilter
ウィジェットがサポートされており、 ただし、使用方法にはいくつかの制限があります。 詳細については、こちらをご覧ください。iOS プラットフォーム ビュー背景フィルターぼかし設計ドキュメント。